// 请求模块
import router from '@/router'
import store from '@/store'
import axios from 'axios'

const request = axios.create({
  // 在时机开发场景下，我们可能会向多个服务器发送请求，获取数据，之前的方式只能写一条基地址
  // axios.create()这个方法会返回应该全新的axios实例对象
  baseURL: 'http://geek.itheima.net/' // 接口的基准路径
})

// 请求拦截器
request.interceptors.request.use(
  function (config) {
    // 请求发起会经过这里
    // config:本次请求的请求配置对象
    const { user } = store.state
    if (user && user.token) {
      config.headers.Authorization = `Bearer ${user.token}`
    }
    // 注意:这里务必要返回config配置对象，否则请求就停在这里出不去了
    // console.log(config)
    return config
  },
  function (error) {
    // 如果请求出错了(还没有发出去)会进入这里
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  // 第一个函数是正常响应的时候要调用的函数
  function (response) {
    return response
  },
  // 第二个函数是响应出错的时候调用的函数
  async function (error) {
    // 函数的形参error就是响应时报的错误
    // 判断错误的状态码是不是401,如果是401代表就是token过期了
    if (error.response && error.response.status === 401) {
      // 获取vuex中保存的user用户数据,在user用户数据中包含了过期的token,和refresh_token
      const { user } = store.state
      // 如果user不存在,或者user里面没有refresh_token
      if (!user || !user.refresh_token) {
        router.push('/login')
        return false
      }
      // 如果refresh_token存在,执行try...catch
      try {
        // 当我们请求刷新用户token的接口之后,接口返回的数据中就包含了最新的token
        // 这里用axios不用request的原因,axios和request不是同一个对象.request是axios重新create出来的一个对象
        // 这里用axios发送请求不用request发送请求的原因是因为request里面headers传的是旧的token,还是一样会报401
        // axios里面重新写headers传的是refresh_token
        const res = await axios({
          method: 'PUT',
          url: 'http://geek.itheima.net/v1_0/authorizations',
          headers: {
            Authorization: `Bearer ${user.refresh_token}`
          }
        })
        console.log(res)
        // 将最新的token和refresh_token保存在vuex中
        store.commit('setUser', {
          token: res.data.data.token,
          refresh_token: user.refresh_token
        })
        // request({url: method:})
        // error.config就是之前发送错误的那次请求的配置对象
        // 按照之前错误的那次请求的配置，重新请求一次
        // console.log(error)
        return request(error.config)
      } catch (error) {
        router.push('/login')
      }
    } else {
      return Promise.reject(error)
    }
  }
)

export default request
